#include "ZombieFaceCleaner.h"
using namespace std;

// int转string
string ZombieFaceCleaner::int2string(int number){
  stringstream sstm;
  sstm<<number;
  return sstm.str();
}

// 执行shell命令，并返回执行结果
string ZombieFaceCleaner::execLinuxCommand(const string& linux_command){
  // 打开文件句柄
  FILE *fp;
  if((fp=popen(linux_command.c_str(),"r"))==NULL){
    return "error: popen error";
  }
  // 读取响应
  char buf[MAXSIZE];
  stringstream sstm;
  while(fgets(buf,MAXSIZE,fp)!=NULL){
    // cout<<"test: "<<string(buf)<<endl;
    sstm<<string(buf);
  }
  // 关闭文件句柄
  if(pclose(fp)==-1){
    return "error: pclose error";
  }
  return sstm.str();
}

// 从face信息中切割出faceID
int ZombieFaceCleaner::getFaceID(string faceInfoString){
  int beginIndex=faceInfoString.find("faceid=")+7;
  faceInfoString=faceInfoString.substr(beginIndex,faceInfoString.length());
  int endIndex=faceInfoString.find(" ");
  string idString=faceInfoString.substr(0,endIndex);
  return atoi(idString.c_str());
}

// 从face信息中切割出out信息：face发出的总数据量
string ZombieFaceCleaner::getFaceOut(string faceInfoString){
  int beginIndex=faceInfoString.find("out={")+5;
  faceInfoString=faceInfoString.substr(beginIndex,faceInfoString.length());
  beginIndex=faceInfoString.find("n ")+2;
  faceInfoString=faceInfoString.substr(beginIndex,faceInfoString.length());
  int endIndex=faceInfoString.find("}");
  string outString=faceInfoString.substr(0,endIndex);
  return outString;  
}

// 找到并清除僵尸Face，并返回一个新的Face映射表（FaceID、FaceOut）
map<int,string> ZombieFaceCleaner::findAndKillZombieFaces(){
  string linux_command="nfdc face | grep tcp";
  map<int,string> newFaceInfoMap;
  // 打开文件句柄
  FILE *fp;
  if((fp=popen(linux_command.c_str(),"r"))==NULL){
    return newFaceInfoMap;
  }
  // 读取每一行：单个Face的信息
  char buf[MAXSIZE];
  while(fgets(buf,MAXSIZE,fp)!=NULL){
    //cout<<"test: "<<string(buf)<<endl;
    //sstm<<string(buf);
    // 解析该Face信息，放入map
    if(string(buf).find("faceid")==0){
      int faceid=getFaceID(string(buf));
      string faceout=getFaceOut(string(buf));
      newFaceInfoMap.insert({faceid,faceout});
      cout<<"faceid: "<<faceid<<" ; "<<"faceout: "<<faceout<<endl;
      // 杀掉out不变的face 
      if(faceInfoMap.find(faceid)!=faceInfoMap.end()&&
           (faceInfoMap.find(faceid)->second)==faceout){ 
        string killcmd="nfdc face destroy "+int2string(faceid);
        cout<<"kill face "+int2string(faceid)+" result: "<<execLinuxCommand(killcmd)<<endl;
      }   
    }	
  }
  // 关闭文件句柄
  if(pclose(fp)==-1){
    return newFaceInfoMap;
  }
  return newFaceInfoMap;
}

// 循环执行清除动作
void ZombieFaceCleaner::startCleaning(int timeInterval){
  while(true){
    cout<<"start cleaning..."<<endl;
    faceInfoMap=findAndKillZombieFaces();
    sleep(timeInterval);
  }
}

